package me.abel.quartz;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import lombok.extern.slf4j.Slf4j;
import me.abel.quartz.entity.QQuartzTaskParam;
import me.abel.quartz.entity.QuartzTask;
import me.abel.quartz.entity.QuartzTaskParam;
import me.abel.quartz.repositories.QuartzTaskParamRepository;
import me.abel.quartz.repositories.QuartzTaskRepository;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.lang3.StringUtils;
import org.quartz.*;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

/**
 * @description
 * @author Abel.li
 * @contact abel0130@163.com
 * @date 2020-11-21
 * @version
 */
@Order(1)
@Component
@Slf4j
public class StartupRunner implements ApplicationRunner {

    private QuartzTaskRepository quartzTaskRepository;
    private QuartzTaskParamRepository quartzTaskParamRepository;
    private SchedulerFactoryBean schedulerFactoryBean;

    public StartupRunner(QuartzTaskRepository quartzTaskRepository, QuartzTaskParamRepository quartzTaskParamRepository, SchedulerFactoryBean schedulerFactoryBean) {
        this.quartzTaskRepository = quartzTaskRepository;
        this.quartzTaskParamRepository = quartzTaskParamRepository;
        this.schedulerFactoryBean = schedulerFactoryBean;
    }

    /**
     * 启动时检查文件目录相关的配置，是否已经在服务器上产生，未生成则自动产生目录，并将系统中对应文件夹下的文件放到服务器文件夹里
     * @param args
     */
    @Override
    public void run(ApplicationArguments args) throws SchedulerException, ClassNotFoundException, IllegalAccessException, InstantiationException {

        /**
         * 系统启动的时候会初始化一个任务
         */
        List<QuartzTask> quartzTasks = quartzTaskRepository.findAll();
        if (CollectionUtils.isEmpty(quartzTasks)) {
            return;
        }

        for (QuartzTask quartz : quartzTasks) {
            Class cls = Class.forName(quartz.getJobClass()) ;
            cls.newInstance();
            //构建job信息
            JobDetail job = JobBuilder.newJob(cls).withIdentity(quartz.getJobName(),
                    quartz.getJobGroup())
                    .withDescription(quartz.getDescription()).build();

            Iterable<QuartzTaskParam> quartzTaskParams = quartzTaskParamRepository.findAll(QQuartzTaskParam.quartzTaskParam.jobId.eq(quartz.getId()));

            Scheduler scheduler = schedulerFactoryBean.getScheduler();

            if (IterableUtils.isEmpty(quartzTaskParams)) {
                // 触发时间点
                CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(quartz.getCronExpression());
                Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger"+quartz.getJobName(), quartz.getJobGroup())
                        .startNow().withSchedule(cronScheduleBuilder).build();
                //交由Scheduler安排触发
                scheduler.scheduleJob(job, trigger);
            } else {
                for (QuartzTaskParam quartzTaskParam : quartzTaskParams) {
                    String jobName = quartz.getJobName() + quartzTaskParam.getJobData();
                    JobDetail jobWithParam = JobBuilder.newJob(cls).withIdentity(jobName,
                            quartz.getJobGroup())
                            .withDescription(quartz.getDescription()).build();
                    String jobData = quartzTaskParam.getJobData();
                    if (StringUtils.isNotBlank(jobData)) {
                        java.lang.reflect.Type type = new TypeToken<Map<String, String>>() {}.getType();
                        Map<String, String> param = new Gson().fromJson(jobData, type);

                        if (!param.isEmpty()) {
                            for (Map.Entry<String, String> entry : param.entrySet()) {
                                jobWithParam.getJobDataMap().put(entry.getKey(), entry.getValue());
                            }
                        }
                    }
                    // 触发时间点
                    CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(quartz.getCronExpression());
                    Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger"+quartz.getJobName() + jobData , quartz.getJobGroup())
                            .startNow().withSchedule(cronScheduleBuilder).build();
                    //交由Scheduler安排触发
                    scheduler.scheduleJob(jobWithParam, trigger);

                    if (jobName.contains("5ZmvO_QYuvuhzlv")) {
                        scheduler.pauseJob(JobKey.jobKey(jobName));
                    }
                }
            }

        }
    }

}
